package com.battch.netty.battcn_netty_5_1_1_jianmaqi;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.FixedLengthFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class EchoLengthClient {

	public static void connect(String host, Integer port){
	    EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        ChannelFuture future = null;
		
        bootstrap.group(group).channel(NioSocketChannel.class)
        .option(ChannelOption.TCP_NODELAY, true)
        .handler(new LoggingHandler(LogLevel.DEBUG))
        .handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel channel) throws Exception {
                channel.pipeline().addLast(new FixedLengthFrameDecoder(EchoConstant.FRAME_LENGTH));
                channel.pipeline().addLast(new StringDecoder());
                channel.pipeline().addLast(new EchoLengthClient.EchoClientHandler());
            }
        });
        
        try {
			//发起异步请求
			future = bootstrap.connect(host, port).sync();
			//等待客户端链路关闭
			future.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
            group.shutdownGracefully();
        }
	}
	
	private static class EchoClientHandler extends ChannelHandlerAdapter{
		private int counter;
        static final String ECHO_REQ = "EchoLengthClient  Hi .Welcome to Netty.";

        public EchoClientHandler() {
        }
        
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush(Unpooled.copiedBuffer(ECHO_REQ.getBytes()));
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            String body = (String) msg;
            System.out.println("EchoLengthClient 接收到的消息 :" + body + "; 当前统计:" + ++counter);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            System.out.println("释放资源:" + cause.getMessage());//不重写将会看到堆栈信息以及资源无法关闭
            ctx.close();
        }
	}
	
	public static void main(String[] args) {
	    EchoLengthClient.connect(EchoConstant.HOST, EchoConstant.ECHO_LENGTH_PORT);
	}

}
